<template>
<div>
  <h1>Data Entry Form</h1>
  <div v-if="count > 0"
       class="alert alert-success">
    <p>{{count}} card&#40;s&#41; successfully entered.</p>
  </div>
  <div v-if="!frontEndWiring || errorPrompt || testResponse || reasons || !browserPasses"
       class="alert alert-danger">
    <strong>Warning</strong>
    <p v-if="!browserPasses">This browser does not work here. You might need to try a modern browser.</p>
    <p v-if="testResponse">Test response from server. No saved data.</p>
    <p v-if="!frontEndWiring">The server has not supplied the correct configuration.</p>
    <p v-if="errorPrompt">{{ errorPrompt }}</p>
    <div v-if="reasons">
      <p>Server responded&#58;</p>
      <ul>
        <li v-for="current in reasons" v-bind:key="current">{{current}}</li>
      </ul>
    </div>
  </div>
  <form v-if="browserPasses"
        @submit.prevent="addCard()">

    <h2>Mode Selection</h2>
    <div v-if="mode"
         class="alert"
         :class="{'alert-success':!devmode,'alert-warning':devmode}"
         >
      <strong>Using {{mode}} mode.</strong><br><br>
      <button type="button"
              class="btn btn-danger"
              @click="setMode('')">Reset Mode</button>&nbsp;
      <button type="button"
              class="btn btn-warning"
              @click="toggleDevMode()">Toggle devmode</button>&nbsp;
      <button v-if="devmode"
              type="button"
              class="btn btn-danger"
              @click="clearCard()"
              >Reset non-persisting values</button>
    </div>
    <div v-if="!mode"
         class="alert alert-info">
      <strong>Select a mode&#58;</strong><br><br>
      <button type="button"
              class="btn btn-primary"
              @click="setMode('events')">Event Mode</button>&nbsp;
      <button type="button"
              class="btn btn-default"
              @click="setMode('traceabilityTags')">TraceabilityTag Mode</button>
    </div>

    <div v-else-if="mode === 'traceabilityTags'">
      <h2>TraceabilityTags</h2>
      <div class="col-xs-12 alert"
           :class="{'alert-danger':!hasTraceabilityTag(),'alert-success':hasTraceabilityTag()}">
        <strong>Select up to three&#58;</strong>

        <FormFieldSelect v-bind:label="'TraceabilityTag (TraceabilityTag 1)'"
                         v-bind:error="errors.traceabilityTag"
                         v-bind:id="'traceabilityTag'"
                         v-bind:data="runtimevals.traceabilityTags"
                         v-bind:value="persist.traceabilityTag"
                         @update="val => persist.traceabilityTag = val"
                         />
        <FormFieldSelect v-bind:label="'TraceabilityTag (TraceabilityTag 2)'"
                         v-bind:error="errors.traceabilityTag2"
                         v-bind:id="'traceabilityTag2'"
                         v-bind:data="runtimevals.traceabilityTags"
                         v-bind:value="persist.traceabilityTag2"
                         @update="val => persist.traceabilityTag2 = val"
                         />
        <FormFieldSelect v-bind:label="'TraceabilityTag (TraceabilityTag 3)'"
                         v-bind:error="errors.traceabilityTag3"
                         v-bind:id="'traceabilityTag3'"
                         v-bind:data="runtimevals.traceabilityTags"
                         v-bind:value="persist.traceabilityTag3"
                         @update="val => persist.traceabilityTag3 = val"
                         />

      </div>
    </div>

    <div v-else-if="mode === 'events'">
      <h2>Event</h2>
      <div v-if="!persist.eventId"
           class="alert alert-danger">
        <strong>No eventId.</strong>
        <p>
          <label>Search for an Event&#58;</label>&nbsp;
          <input type="text" v-model="persist.eventId" placeholder="eventId"/>
        </p>
      </div>
      <div v-else-if="persist.eventId && persist.eventName" class="alert alert-success">
        <strong>Event</strong>
        <p>
          <label>{{persist.eventName}}</label>&nbsp;
          <input type="text" v-model="persist.eventId" readonly/>
          &nbsp;
          <button class="btn btn-danger"
                  type="button"
                  v-on:click="setEvent({name:'',id:''})">X</button>
        </p>
      </div>
      <div v-else-if="persist.eventId" class="alert alert-info">
        <strong>Event</strong>
        <p>
          <label>Search for an Event&#58;</label>&nbsp;
          <input type="text" v-model="persist.eventId"/>
        </p>
        <Autocomplete v-bind:search="persist.eventId"
                      v-bind:endpoint="eventEndpoint"
                      v-bind:limit="10"
                      @response="setEvent"
                      />
      </div>
    </div>

    <!-- ------------------------------------------------------------------ -->
    <!-- ------------------------------------------------------------------ -->
    <!-- Organization Search ---------------------------------------------- -->
    <!-- ------------------------------------------------------------------ -->
    <!-- ------------------------------------------------------------------ -->

    <template>
      <h2 :data-noLazy="noLazy">Organization (Institution)</h2>
      <div v-if="!persist.organizationId || !persist.organizationName"
           class="alert"
           :class="{'alert-warning':!persist.organizationId,'alert-info':persist.organizationId}">
        <strong>{{!persist.organizationId ? 'No ' : ''}}Organization</strong>
        <p>
          <label>Search for an Organization&#58;</label>&nbsp;
          <input type="text" class="form-control" v-model="persist.organizationId"/>
        </p>
        <Autocomplete v-bind:search="persist.organizationId"
                      v-bind:endpoint="organizationEndpoint"
                      v-bind:limit="10"
                      v-bind:devmode="devmode"
                      @response="setOrganization"
                      />
        <p v-show="!persist.organizationId">
          <label>
            Or enter an institution manually to add to the Lead
            instead of an Organization relationship&#58;
          </label>&nbsp;
          <input type="text" class="form-control" v-model="card.organizationName"/>
        </p>
      </div>
      <div v-else
           class="alert alert-success">
        <strong>Organization</strong>
        <p>
          <label>{{persist.organizationName}}</label>&nbsp;
          <input type="text" v-model="persist.organizationId" readonly/>
          &nbsp;
          <button class="btn btn-danger"
                  type="button"
                  v-on:click="setOrganization({name:'',id:''})">X</button>
        </p>
      </div>
    </template>

    <!-- ------------------------------------------------------------------ -->
    <!-- ------------------------------------------------------------------ -->
    <!-- Basic fields below ----------------------------------------------- -->
    <!-- ------------------------------------------------------------------ -->
    <!-- ------------------------------------------------------------------ -->

    <FormFieldInput v-bind:label="'Point of Contact/Staff Name'"
                    v-bind:error="errors.pointOfContact"
                    v-bind:id="'pointOfContact'"
                    v-bind:value="persist.pointOfContact"
                    @update="val => persist.pointOfContact = val"
                    />
    <FormFieldInput v-bind:label="'Point of Contact Date'"
                    v-bind:error="errors.sourceDate"
                    v-bind:id="'sourceDate'"
                    v-bind:type="'date'"
                    v-bind:value="persist.sourceDate"
                    @update="val => persist.sourceDate = val"
                    />
    <FormFieldInput v-bind:label="'First Name'"
                    v-bind:error="errors.firstname"
                    v-bind:id="'firstname'"
                    v-model="card.firstname"
                    v-bind:value="card.firstname"
                    @update="val => card.firstname = val"
                    />
    <FormFieldInput v-bind:label="'Last Name'"
                    v-bind:error="errors.lastname"
                    v-bind:id="'lastname'"
                    v-bind:value="card.lastname"
                    @update="val => card.lastname = val"
                    />
    <FormFieldInput v-bind:label="'Date of Birth'"
                    v-bind:error="errors.birthday"
                    v-bind:id="'birthday'"
                    v-bind:type="'date'"
                    v-bind:value="card.birthday"
                    @update="val => card.birthday = val"
                    />
    <FormFieldInput v-bind:label="'Email'"
                    v-bind:error="errors.email"
                    v-bind:id="'email'"
                    v-bind:type="'email'"
                    v-bind:value="card.email"
                    @update="val => card.email = val"
                    />

    <div class="form-group" title="Residency">
      <label class="col-md-4 control-label">
        Non-domestic Residency?
      </label>
      <div class="col-md-8">
        <input type="radio"
               id="residency1"
               value="international"
               v-model="card.residency"
               />
        <label for="residency1">&nbsp;Yes</label>
        <br>
        <input type="radio"
               id="residency2"
               value=""
               v-model="card.residency"
               />
        <label for="residency2">&nbsp;No</label>
        <div style="display: none;">
          <br>
          <span>Picked: {{ card.residency }}</span>
        </div>
      </div>

      <FormFieldSelect v-if="card.residency === 'international'"
                       v-bind:label="'Country of Citizenship'"
                       v-bind:error="errors.country"
                       v-bind:id="'countryOfCitizenship'"
                       v-bind:data="runtimevals.countries"
                       v-bind:value="card.country"
                       @update="val => card.country = val"
                       />
    </div>

    <div class="form-group">
      <button class="btn btn-info btn-block"
              type="button"
              v-on:click="toggleAddAddressMode()">{{addAddressMode?'Hide':'Show'}} Address Group</button>
    </div>
    <div v-if="addAddressMode"
         class="form-group"
         title="Current Address">
      <FormFieldInput v-bind:label="'Street 1'"
                      v-bind:error="errors.street1"
                      v-bind:id="'street1'"
                      v-bind:value="card.street1"
                      @update="val => card.street1 = val"
                      />
      <FormFieldInput v-bind:label="'Street 2'"
                      v-bind:error="errors.street2"
                      v-bind:id="'street2'"
                      v-bind:value="card.street2"
                      @update="val => card.street2 = val"
                      />
      <FormFieldInput v-bind:label="'City'"
                      v-bind:error="errors.city"
                      v-bind:id="'city'"
                      v-bind:value="card.city"
                      @update="val => card.city = val"
                      />
    </div>

    <br>
    <FormFieldInput v-bind:label="'Postal Code'"
                    v-bind:error="errors.postal"
                    v-bind:id="'postal'"
                    v-bind:value="persist.postal"
                    @update="val => persist.postal = val"
                    />

    <div class="form-group" title="Telephone">
      <FormFieldInput v-bind:label="'Current Phone'"
                      v-bind:error="errors.phone"
                      v-bind:id="'phone'"
                      v-bind:value="card.phone"
                      @update="val => card.phone = val"
                      />

      <label class="col-md-4 control-label">
        Allow SMS?
      </label>
      <div class="col-md-8">
        <input type="radio"
               id="allowSms1"
               value="yes"
               v-model="card.allowSms"
               />
        <label for="allowSms1">&nbsp;Yes</label>
        <br>
        <input type="radio"
               id="allowSms2"
               value=""
               v-model="card.allowSms"
               />
        <label for="allowSms2">&nbsp;No</label>
        <div style="display: none;">
          <br>
          <span>Picked: {{ card.allowSms }}</span>
        </div>
      </div>
    </div>

    <FormFieldSelect v-bind:label="'When do you plan to start?'"
                     v-bind:error="errors.term"
                     v-bind:id="'terms'"
                     v-bind:data="runtimevals.terms"
                     v-bind:value="card.term"
                     @update="val => card.term = val"
                     />
    <FormFieldSelect v-bind:label="'How do you plan to apply?'"
                     v-bind:error="errors.incomingType"
                     v-bind:id="'incomingType'"
                     v-bind:data="[{id:'1',code:'freshman',name:'Freshman'}
                                  ,{id:'2',code:'transfer',name:'Transfer'}
                                  ,{id:'3',code:'PB',name:'Postbaccalaureate'}
                                  ,{id:'4',code:'GR',name:'Graduate'}]"
                     v-bind:value="card.incomingType"
                     @update="val => card.incomingType = val"
                     />

    <div class="form-group">
      <label class="control-label col-md-4" for="interest1">
        Academic Interests<br />
        <small>Choose up to 3</small>
      </label>
      <div class="col-md-8">
        <select v-model="card.interest1" class="form-control" aria-label="Academic Interest 1">
          <option value="">Choose One</option>
          <option v-for="current in runtimevals.programs"
                  v-bind:key="current.id"
                  :value="current.code">{{current.name}}</option>
        </select><br />

        <select v-model="card.interest2" class="form-control" aria-label="Academic Interest 2">
          <option value="">Choose One</option>
          <option v-for="current in runtimevals.programs"
                  v-bind:key="current.id"
                  :value="current.code">{{current.name}}</option>
        </select><br />

        <select v-model="card.interest3" class="form-control" aria-label="Academic Interest 3">
          <option value="">Choose One</option>
          <option v-for="current in runtimevals.programs"
                  v-bind:key="current.id"
                  :value="current.code">{{current.name}}</option>
        </select><br />
      </div>
    </div>

    <FormFieldSelect v-bind:label="'If you are interested in a professional track\
                                   (pre-med, pre-nursing, etc.), select one from the list:'"
                     v-bind:error="errors.tracks"
                     v-bind:id="'tracks'"
                     v-bind:data="runtimevals.tracks"
                     v-bind:value="card.track"
                     @update="val => card.track = val"
                     />
    <FormFieldSelect v-bind:label="'Trivia Poll'"
                     v-bind:error="errors.poll"
                     v-bind:id="'poll'"
                     v-bind:data="[{id:'1',code:'Coffee',name:'Coffee'}
                                  ,{id:'2',code:'Tea',name:'Tea'}
                                  ,{id:'3',code:'Pancakes',name:'Pancakes'}
                                  ,{id:'4',code:'Waffles',name:'Waffles'}
                                  ,{id:'5',code:'Cupcakes',name:'Cupcakes'}
                                  ,{id:'6',code:'Donuts',name:'Donuts'}
                                  ,{id:'7',code:'Mountains',name:'Mountains'}
                                  ,{id:'8',code:'Beaches',name:'Beaches'}]"
                     v-bind:value="card.poll"
                     @update="val => card.poll = val"
                     />

    <hr class="col-xs-12"/>

    <div class="form-group">
      <button class="btn btn-primary btn-lg btn-block"
              :class="{'btn-primary': !formTaken, 'btn-warning': formTaken}">{{formTaken?'Please Wait':'Submit'}}</button>
    </div>
  </form>

  <div v-if="devmode">
    Persisting values&#58;<pre>{{persist}}</pre>
    Other values&#58;<pre>{{card}}</pre>
    Number of submissions&#58;<pre>{{count}}</pre>
    Previous submission&#58;<pre>{{payload}}</pre>
  </div>
</div>
</template>

<script>
import Autocomplete from '@/components/Autocomplete.vue'
import FormFieldInput from '@/components/FormFieldInput.vue'
import FormFieldSelect from '@/components/FormFieldSelect.vue'

export default {
    name: "DataEntryForm",
    components: {
        Autocomplete,
        FormFieldInput,
        FormFieldSelect,
    },
    computed: {
        browserPasses: function() { return 'fetch' in window },
    },
    data() {
        return {
            addAddressMode: false,
            devmode: false,
            mode: '',
            count: 0,
            //NOTE: defined in mounted
            persist: '',
            //NOTE: defined in resetCard
            card: '',
            payload: '',
            errors: '',
            errorPrompt: '',
            reasons: '',
            testResponse: false,
            formTaken: false,
            frontEndWiring: (document.getElementById("frontEndWiring")).textContent,
            runtimevals: {
                traceabilityTags: '',
                programs: '',
                tracks: '',
                terms: '',
            },
            noLazy: 'noLazy-foo',
            organizationEndpoint: (JSON.parse((document.getElementById("frontEndWiring")).textContent)).endpoints.organizations,
            eventEndpoint: (JSON.parse((document.getElementById("frontEndWiring")).textContent)).endpoints.events,
            traceabilityTagEndpoint: (JSON.parse((document.getElementById("frontEndWiring")).textContent)).endpoints.traceabilityTags,
        }
    },
    methods: {
        toggleAddAddressMode: function() { this.addAddressMode = !this.addAddressMode },
        toggleDevMode: function() { this.devmode = !this.devmode },
        setMode: function(val) {
            this.mode = val
            this.setEvent({name:'',id:''})
            this.persist.traceabilityTag = ''
            this.persist.traceabilityTag2 = ''
            this.persist.traceabilityTag3 = ''
        },
        hasTraceabilityTag: function() {
            return this.persist.traceabilityTag || this.persist.traceabilityTag2 || this.persist.traceabilityTag3
        },
        setEvent: function(item) {
            this.persist.eventName = item.name
            this.persist.eventId = item.id
        },
        setOrganization: function(item) {
            this.noLazy = "noLazy-" + Math.random()
            this.persist.organizationName = item.name
            this.persist.organizationId = item.id
            // console.log(this.noLazy)
        },
        clearCard: function() {
            this.resetCard(this, "card")
        },
        resetCard: function(that, ref) {
            that[ref] = {
                allowSms: '',
                city: '',
                street1: '',
                street2: '',
                telephone: '',
                birthday: '',
                country: '',
                email: '',
                firstname: '',
                incomingType: '',
                interest1: '',
                interest2: '',
                interest3: '',
                lastname: '',
                phone: '',
                poll: '',
                track: '',
                residency: '',
                term: ''
            }
        },
        releaseForm: function(message) {
            //NOTE: More throttling for accidental clicks.
            setTimeout(() => {
                this.formTaken = false;
                this.errorPrompt = message;
            }, 500)
        },
        addCard: function() {

            if (this.formTaken !== true) {
                this.formTaken = true
            } else {
                return
            }

            this.payload = ''

            this.card.organizationId = this.persist.organizationId
            this.card.eventId = this.persist.eventId
            this.card.postal = this.persist.postal
            this.card.traceabilityTag = this.persist.traceabilityTag
            this.card.traceabilityTag2 = this.persist.traceabilityTag2
            this.card.traceabilityTag3 = this.persist.traceabilityTag3
            this.card.pointOfContact = this.persist.pointOfContact
            this.card.sourceDate = this.persist.sourceDate

            this.payload = this.card

            let endpoint = (this.frontEndWiring)
                ? (JSON.parse(this.frontEndWiring)).endpoints.submit
                : './endpoint.aspx'

            this.testResponse = (this.frontEndWiring)
                ? (JSON.parse(this.frontEndWiring)).testResponse
                : false

            if (endpoint) {
                fetch(endpoint,
                      {
                          method: 'POST',
                          cache: 'no-cache',
                          headers: {
                              'Content-Type': 'application/json'
                          },
                          body: JSON.stringify(this.payload)
                      })
                    .then(response => response.json())
                    .then(json => {
                        if (json.status === "success") {
                            this.reasons = ''
                            this.errors = ''
                            this.resetCard(this, "card")
                            ++this.count
                            this.releaseForm("")
                        } else if (json.status === "failure") {
                            this.reasons = ''
                            this.errors = ''
                            this.releaseForm("General server failure. Contact an admin if it happens again.")
                        } else if (json.reason) {
                            this.reasons = json.reason
                            this.errors = json.errors
                            this.releaseForm("")
                        } else {
                            this.releaseForm(`Response failed. ${json.status || 'Unexpected response.'}`)
                        }
                    })
                    .catch(error => {
                        this.releaseForm(`Request failed. ${error}`)
                    })
            } else {
                this.releaseForm("No configuration.")
            }
        },
    },
    mounted() {
        function getData(endpoint, that, bucket, refs, errorPrompt) {
            if (endpoint) {
                fetch(endpoint)
                    .then(response => response.json())
                    .then(json => {
                        if (json) {
                            that[bucket][refs] = json
                        } else {
                            that[errorPrompt] = "Response failed."
                        }
                    })
                    .catch(error => {
                        that[errorPrompt] = `Request failed. ${error}`
                    })
            } else {
                that[errorPrompt] = "No configuration."
            }
        }

        const endpoints = (this.frontEndWiring)
              ? (JSON.parse(this.frontEndWiring)).endpoints
              : undefined

        getData(endpoints.countries, this, "runtimevals", "countries", "errorPrompt")
        getData(endpoints.traceabilityTags, this, "runtimevals", "traceabilityTags", "errorPrompt")
        getData(endpoints.programs, this, "runtimevals", "programs", "errorPrompt")
        getData(endpoints.tracks, this, "runtimevals", "tracks", "errorPrompt")
        getData(endpoints.terms, this, "runtimevals", "terms", "errorPrompt")

        this.resetCard(this, "card")
        this.persist = {
            organizationId: '',
            pointOfContact: '',
            sourceDate: '',
            eventId: '',
            postal: '',
            traceabilityTag2: '',
            traceabilityTag3: '',
            traceabilityTag: '',
        }
    },
}
</script>

<style scoped>
hr {
    padding:0;
}
</style>
